"""
类型管理API端点
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, Response
from motor.motor_asyncio import AsyncIOMotorDatabase

from app.core.database import get_database
from app.core.response import success_response, error_response, ErrorTypes, ApiResponse
from app.api.deps import get_current_user
from app.models.user import User
from app.models.type import TypeCreate, TypeUpdate, TypeResponse, ModuleType
from app.services.type_service import type_service, TypeNotModifiedError

router = APIRouter()

@router.get("/", response_model=ApiResponse, summary="获取类型列表")
async def get_types(
    module_type: Optional[str] = Query(None, description="模块类型"),
    include_disabled: bool = Query(False, description="是否包含已禁用的类型"),
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
):
    """获取类型列表"""
    try:
        query = {}
        if module_type:
            if module_type not in [m.value for m in ModuleType]:
                raise HTTPException(status_code=400, detail=f"无效的模块类型: {module_type}")
            query["module_type"] = module_type
        
        # 默认只返回启用的类型
        if not include_disabled:
            query["is_enabled"] = True

        cursor = db.types.find(query).sort("sort_order", 1)
        types = await cursor.to_list(length=None)
        
        # 将ObjectId转换为字符串
        for t in types:
            t["_id"] = str(t["_id"])
            
        return success_response(data=types)

    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"获取类型列表失败: {str(e)}"
        )

@router.get("/all/options", response_model=ApiResponse, summary="获取所有模块的类型选项")
async def get_all_type_options(
    force_refresh: bool = Query(False, description="是否强制刷新缓存"),
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
):
    """获取所有模块的类型选项"""
    try:
        options = await type_service.get_all_type_options(db, force_refresh)
        return success_response(data=options)
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"获取所有模块的类型选项失败: {str(e)}"
        )

@router.get("/{type_id}", response_model=ApiResponse, summary="获取类型详情")
async def get_type(
    type_id: str,
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
):
    """获取类型详情"""
    try:
        from bson import ObjectId
        
        # 验证ID格式
        if not ObjectId.is_valid(type_id):
            return error_response(
                error_type=ErrorTypes.VALIDATION_ERROR,
                message="无效的类型ID格式"
            )
        
        # 查询类型
        type_item = await db.types.find_one({"_id": ObjectId(type_id)})
        
        if not type_item:
            return error_response(
                error_type=ErrorTypes.NOT_FOUND,
                message="未找到指定的类型"
            )
        
        # 转换为响应格式
        type_response = TypeResponse(
            id=str(type_item["_id"]),
            name=type_item["name"],
            code=type_item["code"],
            module_type=type_item["module_type"],
            description=type_item.get("description"),
            color=type_item.get("color", "#1890ff"),
            sort_order=type_item.get("sort_order", 0),
            is_enabled=type_item.get("is_enabled", True),
            created_at=type_item.get("created_at"),
            updated_at=type_item.get("updated_at")
        )
        
        return success_response(
            data=type_response,
            message="获取类型详情成功"
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"获取类型详情失败: {str(e)}"
        )

@router.post("/", response_model=ApiResponse, summary="创建类型")
async def create_type(
    type_item: TypeCreate,
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
):
    """创建类型"""
    try:
        from datetime import datetime
        from bson import ObjectId
        
        # 验证模块类型
        if type_item.module_type not in [m.value for m in ModuleType]:
            return error_response(
                error_type=ErrorTypes.VALIDATION_ERROR,
                message=f"无效的模块类型: {type_item.module_type}"
            )
        
        # 检查代码是否已存在
        existing = await db.types.find_one({
            "module_type": type_item.module_type,
            "code": type_item.code
        })
        
        if existing:
            return error_response(
                error_type=ErrorTypes.ALREADY_EXISTS,
                message=f"类型代码 '{type_item.code}' 在 {type_item.module_type} 模块中已存在"
            )
        
        # 准备数据
        now = datetime.utcnow()
        type_data = {
            "name": type_item.name,
            "code": type_item.code,
            "module_type": type_item.module_type,
            "description": type_item.description,
            "color": type_item.color or "#1890ff",
            "sort_order": type_item.sort_order or 0,
            "is_enabled": type_item.is_enabled if type_item.is_enabled is not None else True,
            "created_at": now,
            "updated_at": now
        }
        
        # 插入数据
        result = await db.types.insert_one(type_data)
        
        # 获取创建的类型
        created_type = await db.types.find_one({"_id": result.inserted_id})
        
        # 转换为响应格式
        type_response = TypeResponse(
            id=str(created_type["_id"]),
            name=created_type["name"],
            code=created_type["code"],
            module_type=created_type["module_type"],
            description=created_type.get("description"),
            color=created_type.get("color", "#1890ff"),
            sort_order=created_type.get("sort_order", 0),
            is_enabled=created_type.get("is_enabled", True),
            created_at=created_type.get("created_at"),
            updated_at=created_type.get("updated_at")
        )
        
        # 刷新缓存
        await type_service.refresh_cache(type_item.module_type)
        
        return success_response(
            data=type_response,
            message="创建类型成功"
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"创建类型失败: {str(e)}"
        )

@router.put("/{type_id}", response_model=ApiResponse, summary="更新类型")
async def update_type(
    type_id: str,
    type_item: TypeUpdate,
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
):
    """更新类型"""
    try:
        from datetime import datetime
        from bson import ObjectId
        
        # 验证ID格式
        if not ObjectId.is_valid(type_id):
            return error_response(
                error_type=ErrorTypes.VALIDATION_ERROR,
                message="无效的类型ID格式"
            )
        
        # 查询类型
        existing = await db.types.find_one({"_id": ObjectId(type_id)})
        
        if not existing:
            return error_response(
                error_type=ErrorTypes.NOT_FOUND,
                message="未找到指定的类型"
            )
        
        # 如果更新代码，检查是否与其他类型冲突
        if type_item.code and type_item.code != existing["code"]:
            code_conflict = await db.types.find_one({
                "_id": {"$ne": ObjectId(type_id)},
                "module_type": existing["module_type"],
                "code": type_item.code
            })
            
            if code_conflict:
                return error_response(
                    error_type=ErrorTypes.ALREADY_EXISTS,
                    message=f"类型代码 '{type_item.code}' 在 {existing['module_type']} 模块中已存在"
                )
        
        # 准备更新数据
        update_data = {}
        if type_item.name is not None:
            update_data["name"] = type_item.name
        if type_item.code is not None:
            update_data["code"] = type_item.code
        if type_item.description is not None:
            update_data["description"] = type_item.description
        if type_item.color is not None:
            update_data["color"] = type_item.color
        if type_item.sort_order is not None:
            update_data["sort_order"] = type_item.sort_order
        if type_item.is_enabled is not None:
            update_data["is_enabled"] = type_item.is_enabled
        
        update_data["updated_at"] = datetime.utcnow()
        
        # 更新数据
        await db.types.update_one(
            {"_id": ObjectId(type_id)},
            {"$set": update_data}
        )
        
        # 获取更新后的类型
        updated_type = await db.types.find_one({"_id": ObjectId(type_id)})
        
        # 转换为响应格式
        type_response = TypeResponse(
            id=str(updated_type["_id"]),
            name=updated_type["name"],
            code=updated_type["code"],
            module_type=updated_type["module_type"],
            description=updated_type.get("description"),
            color=updated_type.get("color", "#1890ff"),
            sort_order=updated_type.get("sort_order", 0),
            is_enabled=updated_type.get("is_enabled", True),
            created_at=updated_type.get("created_at"),
            updated_at=updated_type.get("updated_at")
        )
        
        # 刷新缓存
        await type_service.refresh_cache(updated_type["module_type"])
        
        return success_response(
            data=type_response,
            message="更新类型成功"
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"更新类型失败: {str(e)}"
        )

@router.delete("/{type_id}", response_model=ApiResponse, summary="删除类型")
async def delete_type(
    type_id: str,
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
):
    """删除类型"""
    try:
        from bson import ObjectId
        
        # 验证ID格式
        if not ObjectId.is_valid(type_id):
            return error_response(
                error_type=ErrorTypes.VALIDATION_ERROR,
                message="无效的类型ID格式"
            )
        
        # 查询类型
        type_item = await db.types.find_one({"_id": ObjectId(type_id)})
        
        if not type_item:
            return error_response(
                error_type=ErrorTypes.NOT_FOUND,
                message="未找到指定的类型"
            )
        
        # 删除类型
        await db.types.delete_one({"_id": ObjectId(type_id)})
        
        # 刷新缓存
        await type_service.refresh_cache(type_item["module_type"])
        
        return success_response(
            data={"id": type_id},
            message="删除类型成功"
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"删除类型失败: {str(e)}"
        )

@router.post("/cache/refresh", response_model=ApiResponse, summary="刷新类型缓存")
async def refresh_type_cache(
    module_type: Optional[str] = Query(None, description="模块类型，不传则刷新所有模块"),
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
):
    """刷新类型缓存"""
    try:
        if module_type:
            # 验证模块类型
            if module_type not in [m.value for m in ModuleType]:
                return error_response(
                    error_type=ErrorTypes.VALIDATION_ERROR,
                    message=f"无效的模块类型: {module_type}"
                )
            
            # 刷新指定模块的缓存
            result = await type_service.refresh_cache(module_type)
            
            module_name_map = {
                "task": "任务",
                "project": "项目",
                "defect": "缺陷",
                "requirement": "需求",
                "test_case": "测试用例"
            }
            module_name = module_name_map.get(module_type, module_type)
            
            if result["refreshed_count"] > 0:
                message = f"刷新“{module_name}”模块类型缓存成功"
            else:
                message = f"“{module_name}”模块没有需要刷新的缓存"
        else:
            # 刷新所有缓存
            result = await type_service.refresh_cache()
            refreshed_count = result["refreshed_count"]
            refreshed_modules = result["refreshed_modules"]
            
            if refreshed_count > 0:
                module_names = [m.replace("_", "") for m in refreshed_modules]
                message = f"刷新所有类型缓存成功，共刷新 {refreshed_count} 个模块: {', '.join(module_names)}"
            else:
                message = "没有需要刷新的缓存"
        
        return success_response(
            data=result,
            message=message
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"刷新类型缓存失败: {str(e)}"
        )

@router.post("/initialize", response_model=ApiResponse, summary="初始化默认类型")
async def initialize_types(
    module_type: str = Query(..., description="要初始化的模块类型"),
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
):
    """初始化指定模块的默认类型"""
    try:
        created_count = await type_service.initialize_default_types(db, module_type)
        return success_response(
            data={"created_count": created_count},
            message=f"为模块 {module_type} 初始化了 {created_count} 个默认类型"
        )
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"初始化默认类型失败: {str(e)}"
        )


